www.gusucode.com > VC++ RingSDK界面库 > VC++ RingSDK界面库/code/libsrc/ringdows/controls.cpp
/********************************************************************** // // // ########## ###### ######### # ###### # // ############# ########### ######### ######### ### // ######## # ### ## ############# ## ## ##### # #### // #### ## ## ### ### ### # # ##### ##### // # ### # # ## ## ## ## ### // ## ###### ## ## #### #### # # ## // ######### ### ## ### ####### ###### ## ## ### // ###### ## ###### ## ## #### # ## #### // ####### ## ###### ## ### ## ## ### ###### // ######### ## ###### ## ###### ### ## ### # ##### // ## ###### ####### ### #### ## ## ####### ######## ## #### // ## #### ### # ### ### ## ########## ###### ## #### // ## ## ## ######### #### # ## // # ### // ## // ### // ## // // // 临风程序界面类库 ringdows.lib //作者:临风 // //版本:1.0 // //声明:本类库可以自由使用而不须对作者作出任何回报,但作者希望能得到 // 你的鼓励和支持。你可以对类库源码作出修改和改进,但希望你能在 // 修改的同时给作者一份同样的副本。 // 本类库不得用于任何商业用途,如确实需要,请与作者联系。 // //e-mail:ringphone@sina.com // //原文件名:controls.cpp // //本文件说明:控件基类实现。 // **********************************************************************/ #define MAKE_SELF_LIB //#ifndef __BORLANDC__ #include "ringdows.h" //#else //#include "include\ringdows.h" //#endif //RingOwnerDrawer* RingControls::m_drawer = NULL; RingCtrlWnd::~RingCtrlWnd() { //RingBaseWnd析构会自动判断是否需要Detach } HWND RingCtrlWnd::Create(LPCTSTR szTitle,LPCTSTR szClass,DWORD dwStyle,HWND hParentWnd/*=NULL*/,DWORD dwExStyle,HMENU hMenu,int x,int y,int width,int height) { if(IsWindow()) return m_hWnd; if(hParentWnd == NULL) hParentWnd = m_parent->Handle(); //else // SetParentObj(GetWindowPtr(hParentWnd)); m_hWnd = CreateWindowEx( dwExStyle, szClass, szTitle, dwStyle, x, y, width, height, hParentWnd, hMenu, GetInstance(), NULL ); RingBaseWnd::Attach(m_hWnd); m_ID = (UINT)hMenu; return m_hWnd; } LRESULT RingCtrlWnd::DefaultProc(RINGPARAMS& param) { if(param.uMsg == WM_NCDESTROY) { CallWindowProc(m_DefProc,m_hWnd,param.uMsg,param.wParam,param.lParam); //析构时无需Detach,RingBaseWnd析构时会Detach OnNcDestroy(); return 0; } return CallWindowProc(m_DefProc,m_hWnd,param.uMsg,param.wParam,param.lParam); } RingControls::RingControls() { m_brush = NULL;//(HBRUSH)GetStockObject(NULL_BRUSH/*DC_BRUSH*/); m_bNotifiParentKeyEvent = FALSE; m_buf = NULL; m_bufsize = 0; m_crTextColor = GetSysColor(COLOR_WINDOWTEXT); m_crBkgColor = CLR_INVALID; m_windowType = ITIS_DLGITEM; m_bOwnerDraw = FALSE; m_drawer = NULL; } RingControls::~RingControls() { m_buf=(LPSTR)Del(m_buf); if(m_brush && m_brush != (HBRUSH)CLR_INVALID) DeleteObject(m_brush); } void RingControls::SetAutoSize(BOOL bAuto) { if(bAuto) m_ExStyle |= RTV_FITPARENTSIZE; else m_ExStyle &= ~RTV_FITPARENTSIZE; } LRESULT RingControls::RingdowProc(HWND hWnd,RINGPARAMS param) { if(m_drawer) { LRESULT res = m_drawer->DrawProc(this,param); if(res != 0) return res; } if(m_bNotifiParentKeyEvent) { if(param.uMsg == WM_KEYDOWN || param.uMsg == WM_KEYUP || param.uMsg == WM_CHAR) //父窗口如想截取该消息不让控件继续处理必须返回非0值 if(SendMessage(m_parent->Handle(),param)) return 0; } switch(param.uMsg) { case WM_DESTROY: return OnDestroy(param); case WM_DOCKSTATECHANGE: return OnDockStateChange(param.shortval.low,param.shortval.high); case WM_GETDRAGRECTS: if(param.lpnmhdr->hwndFrom == m_hWnd) return OnGetDragRects(param.lpnmhdr->code,(LPRECT)param.wParam); } return DefaultProc(param); } int RingControls::OnDockStateChange(int stateOld,int stateNew) { return SendMessage(m_parent->Handle(),WM_DOCKSTATECHANGE,MAKELONG(stateOld,stateNew),(LPARAM)m_hWnd); } BOOL RingControls::OnGetDragRects(int state,LPRECT lprc) { //return SendMessage(m_parent->Handle(),WM_GETDRAGRECTS,(WPARAM)lprc,(LPARAM)m_hWnd); //先向父窗口查询失败然后发过来的消息,没必要再次查询 return 0; } BOOL RingControls::OnParentNotify(HWND hWnd,UINT uMsg,UINT wParam,LONG lParam) { switch(uMsg) { case WM_DOCKSITESIZECHANGE: hWnd = NULL; //标记是WM_DOCKSITESIZECHANGE消息,DOCKSITE调整尺寸 case WM_SIZE: return OnFitSize(hWnd,wParam,lParam); case WM_DRAWITEM: //m_bOwnerDraw=TRUE表示由父窗口处理 if(!m_bOwnerDraw) if(m_ID == wParam) return OnDrawItem((LPDRAWITEMSTRUCT)lParam); return FALSE; } return FALSE; } BOOL RingControls::OnFitSize(HWND hWnd,WPARAM wParam,LPARAM lParam) { if(m_ExStyle & RTV_FITPARENTSIZE) { if(wParam == -1) //-1表示根据lParam的值设置大小,未来支持,暂时不会用到 SetPos(0,0,LOWORD(lParam),HIWORD(lParam),NULL,SWP_NOMOVE|SWP_NOZORDER);//SWP_NOACTIVATE|SWP_NOREDRAW); else { RECT rc; //必须m_parent->GetClientRect才返回正确的RECT RingBaseWnd* parent = GetWindowPtr(GetParent()); if(parent) parent->GetClientRect(&rc); else ::GetClientRect(GetParent(),&rc); MoveWindow(m_hWnd,rc.left,rc.top,rc.right - rc.left,rc.bottom - rc.top,TRUE); if(hWnd == NULL) { //WM_DOCKSITESIZECHANGE消息,DockSite尺寸变动,有可能覆盖控件, //某些控件如ListView等不会刷新导致界面会花,因此须刷新 InvalidateRect(m_hWnd,NULL,TRUE); } } return TRUE; } return FALSE; } int RingControls::GetInt(int index/*=INDEX_CURSEL*/) { return (int)GetDlgItemInt(m_parent->Handle(),m_ID,NULL,TRUE); } LPCTSTR RingControls::GetText(int index/*=INDEX_CURSEL*/, int size/*=RBUF_SIZE*/, LPTSTR lpBuf/*=NULL*/) { LPTSTR lpstr = lpBuf; if(lpstr == NULL && GetBuffer(size)) lpstr = m_buf; if(lpstr) { memset(lpstr,0,size); GetItemText(index,lpstr,size); //GetItemText有可能重新分配m_buf,因此需以下判断 if(lpstr != m_buf && lpBuf == NULL) return m_buf; else return lpstr; } else return ""; } int RingControls::GetItemText(int,LPTSTR lpBuf,int size) { return GetWindowText(m_hWnd,lpBuf,size); } BOOL RingControls::SetValue(int val,int index/*=INDEX_CURSEL*/) { return SetDlgItemInt(GetParent(),m_ID,val,TRUE); } BOOL RingControls::SetValue(LPCTSTR lpszVal,int index/*=INDEX_CURSEL*/) { return SetDlgItemText(GetParent(),m_ID,lpszVal); } int RingControls::GetBuffer(int size) { //分配内存,比申请尺寸大4以防溢出,但不记录该实际尺寸 //m_bufsize仍为申请尺寸 if(m_buf == NULL && size > 0) { m_buf = (LPSTR)New(size + 4); if(m_buf) m_bufsize = size; } else if(size > m_bufsize) { LPSTR temp = (LPSTR)New(size + 4); if(temp) { m_bufsize = size; Del(m_buf); m_buf = temp; } } return m_bufsize; } BOOL RingControls::TypeMatched(UINT id) { HWND hwnd = GetDlgItem(m_parent->Handle(),id); if(hwnd) return TypeMatched(hwnd); return FALSE; } BOOL RingControls::TypeMatched(HWND hWnd) { char szClass[80]; memset(szClass,0,80); GetClassName(hWnd,szClass,80); return (strcmpi(WndClassName(),szClass) == 0); } BOOL RingControls::Attach(UINT uId,RingBaseWnd* parent/*=NULL*/) { if(m_parent == this && parent) m_parent = parent; m_hWnd = GetDlgItem(m_parent->Handle(),uId); return Attach(m_hWnd); } BOOL RingControls::Attach(HWND hWnd) { if(RingBaseWnd::Attach(hWnd)) { m_ID = GetWindowLong(hWnd,GWL_ID); //m_ExStyle有可能被SetAutoSize设置过,因此需或操作 m_ExStyle = GetWindowLong(m_hWnd,GWL_EXSTYLE) | m_ExStyle; //m_brush = (HBRUSH)GetClassLong(m_hWnd,GCL_HBRBACKGROUND); return TRUE; } return FALSE; } BOOL RingControls::Create(DWORD dwStyle,DWORD dwExStyle,LPCTSTR szInitText,UINT uId,int x,int y,int width,int height) { if(m_hWnd && IsWindow()) return TRUE; m_ExStyle = dwExStyle; if((dwExStyle & RTV_FITPARENTSIZE)) { RECT rc; m_parent->GetClientRect(&rc); x = y = 0; width = rc.right; height = rc.bottom; dwExStyle &= ~RTV_FITPARENTSIZE; } m_hWnd = RingCtrlWnd::Create( szInitText, WndClassName(), WS_CHILD | WS_VISIBLE | dwStyle, 0,dwExStyle, (HMENU)uId,x,y,width,height); if(m_hWnd) { //m_brush = (HBRUSH)GetClassLong(m_hWnd,GCL_HBRBACKGROUND); ringFont rf = (HFONT)GetStockObject(DEFAULT_GUI_FONT); rf.SetWindowFont(m_hWnd); } return (BOOL)m_hWnd; } void RingControls::SetOwnerDraw(BOOL bParentDraw,UINT uItemStyle) { m_bOwnerDraw = bParentDraw; if(uItemStyle != 0xFFFFFFFF && (GetStyle() & uItemStyle) != uItemStyle) ReplaceStyle(0,uItemStyle); } BOOL RingControls::SetBkColor(COLORREF crColor) { m_crBkgColor = crColor; HDC hDC = GetDC(m_hWnd); ::SetBkColor(hDC,crColor); ReleaseDC(m_hWnd,hDC); if(m_brush) DeleteObject(m_brush); if(crColor == CLR_INVALID) m_brush = (HBRUSH)GetStockObject(NULL_BRUSH); else m_brush = CreateSolidBrush(crColor); return (BOOL)m_brush; } void RingControls::SetFont(LPCTSTR szFontName,int size,int nStyle,COLORREF crText) { m_crTextColor = crText; m_font.SetWindowFont(m_hWnd,szFontName,size,nStyle); } void RingControls::SetTextColor(COLORREF crColor) { m_crTextColor = crColor; } LRESULT RingControls::SetColors(HDC hDC) { //if(m_crBkgColor != 0xFFFFFFFF) { ::SetTextColor(hDC,m_crTextColor); //SelectObject(hDC,m_brush); SetBkMode(hDC,TRANSPARENT); //::SetBkColor(param.hdc,0);//((GetSysColor(COLOR_WINDOW)); //SetROP2(param.hdc,R2_BLACK); //if(m_brush == NULL) // SetBkColor(GetSysColor(COLOR_WINDOW)); } //SetBrushOrgEx(hDC,0,0,NULL); return (LONG)m_brush; } void RingControls::SetMouseTrack(RINGPARAMS& param) { if((param.uMsg >= WM_MOUSEFIRST) && (param.uMsg <= WM_MOUSELAST)) { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.hwndTrack = m_hWnd; tme.dwHoverTime = 10;//HOVER_DEFAULT; tme.dwFlags = TME_LEAVE | TME_HOVER; TrackMouseEvent(&tme); } }